/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package runebound.modelo.heores;

import java.util.ArrayList;
import runebound.modelo.heores.items.Item;
import java.util.List;
import runebound.modelo.Miniatura;
import runebound.modelo.heores.experiencia.Experiencia;
import runebound.modelo.Habilidad;
import runebound.modelo.TipoAmenaza;
import runebound.modelo.heores.experiencia.Atributo;
import runebound.modelo.heores.items.ItemPasiva;

/**
 *
 * @author malopez
 */
public class Heroe extends Miniatura{
    
    private String nombre;
    private String descripcion;
    
    /*
    Cantidad de Oro
    */
    private int oro;
    /*
     Experiencia pendiente por gastar
    */
    private int puntosExperiencia;
    /*
    Experiencia adquirida
    */
    private List<Experiencia> experiencia;
    /*
     Objetos
    */
    private List<Item> items;
    /*
    Solo 2
    */
    private Aliado[] aliados;
    
    private int fatiga;
    
    private EstadoPersistente estadoPersistente;

    public Heroe() {
        this.estadoPersistente=new EstadoPersistente();
        this.aliados = new Aliado[2];
        this.items = new ArrayList<>();
        this.experiencia = new ArrayList<>();
        this.oro=0;
        this.puntosExperiencia = 0;
    }
    
    

    public void ampliarOro(int oro) {
        this.oro+=oro;
    }
    /**
     * Devuelve el valor de una habilidad para un heroe, chequeando sus: objetos experiencia y valores iniciaes
     * @param habilidad
     * @return 
     */
    public int getValorHabilidad(Habilidad habilidad) {
        //TODO controlar las distintas habilidades
        int rst = 0;
        switch (habilidad) {
            case DIPLOMACIA:
                rst=this.getValorMagia();
                break;
            case ESCONDER:
                rst=this.getValorMente();
                break;
            case FISICO:
                rst=this.getValorFisico();
                break;
            case MAGIA:
                rst=this.getValorMagia();
                break;
            case MENTE:
                rst=this.getValorMente();
                break;
            case NADAR:
                rst=this.getValorFisico();
                break;
            case RESISTIR:
                rst=this.getValorMagia();
                break;
            case TREPAR:
                rst=this.getValorMente();
                break;
            case SALTAR:
                rst=this.getValorFisico();
                break;
            case MANIPULAR:
                rst=this.getValorMente();
                break;
        }
        return rst;
        
    }

    /**
     * Agota una cantidad de  fatiga determinada
     * @param fatigaConsumida 
     */
    public void agota(int fatigaConsumida) {
        this.getEstadoPersistente().addAgotamiento(fatigaConsumida);
    }

    /**
     * Actualiza el valor con  experiencia
     * @retun 
     */
    @Override
    public int getValorFisico() {
        int valor =  super.getValorFisico(); 
        return this.procesarExperienciaHeroe(valor,Atributo.FISICO);
    }

    /**
     * Actualiza el valor con  la experiencias
     * @return 
     */
    @Override
    public int getValorMagia() {
        int valor = super.getValorMagia(); 
        return this.procesarExperienciaHeroe(valor,Atributo.MAGIA);
    }

    /**
     * Actualiza el valor con la experiencia
     * @return 
     */
    @Override
    public int getValorMente() {
        int valor =  super.getValorMente(); 
        return this.procesarExperienciaHeroe(valor,Atributo.MENTE);
    }
    
    
    
    /**
     * Actualiza el valor con los objetos y experiencia
     * @return 
     */
    
    public int getValorCombateFisico() {
        int valor =  super.getValorFisico(); 
        valor= this.procesarExperienciaHeroe(valor,Atributo.FISICO);
        valor = this.procesarItems(valor, Atributo.FISICO);
        return valor;
    }

    /**
     * Actualiza el valor con los objetos y la experiencias
     * @return 
     */
    
    public int getValorCombateMagia() {
        int valor =  super.getValorMagia();
        valor =  this.procesarExperienciaHeroe(valor,Atributo.MAGIA);
        valor = this.procesarItems(valor, Atributo.MAGIA);
        return valor;
    }

    /**
     * Actualiza el valor con los objetos y la experiencia
     * @return 
     */
    
    public int getValorCombateDistancia() {
        int valor = super.getValorMente(); 
        valor =  this.procesarExperienciaHeroe(valor,Atributo.MENTE);
        valor = this.procesarItems(valor,Atributo.MENTE);
        return valor;
    }

    /**
     * Actualiza el valor con los objetos y la experiencia
     * @return 
     */
    @Override
    public int getVida() {
        int valor =  super.getVida(); 
        return this.procesarExperienciaHeroe(valor,Atributo.VIDA);
    }

    /**
     * Actualiza el valor con los objetos y la experiencia
     * @return 
     */ 
    public int getFatiga() {
        int valor = fatiga;
        return this.procesarExperienciaHeroe(valor,Atributo.FATIGA);
    }

    /**
     * @return the nombre
     */
    public String getNombre() {
        return nombre;
    }

    /**
     * @return the descripcion
     */
    public String getDescripcion() {
        return descripcion;
    }

    /**
     * @return the oro
     */
    public int getOro() {
        return oro;
    }

    /**
     * @return the puntosExperiencia
     */
    public int getPuntosExperiencia() {
        return puntosExperiencia;
    }

    /**
     * @return the experiencia
     */
    public List<Experiencia> getExperiencia() {
        return experiencia;
    }

    /**
     * @return the items
     */
    public List<Item> getItem() {
        return items;
    }

    /**
     * @return the aliados
     */
    public Aliado[] getAliados() {
        return aliados;
    }

    /**
     * @return the estadoPersistente
     */
    public EstadoPersistente getEstadoPersistente() {
        return estadoPersistente;
    }

    @Override
    public boolean isVivo() {
        return this.getVida()>this.getEstadoPersistente().getHeridas();
    }

    /**
     * @param nombre the nombre to set
     */
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    /**
     * @param descripcion the descripcion to set
     */
    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    /**
     * @param oro the oro to set
     */
    public void setOro(int oro) {
        this.oro = oro;
    }

    /**
     * @param puntosExperiencia the puntosExperiencia to set
     */
    public void setPuntosExperiencia(int puntosExperiencia) {
        this.puntosExperiencia = puntosExperiencia;
    }

    /**
     * @param experiencia the experiencia to set
     */
    public void setExperiencia(List<Experiencia> experiencia) {
        this.experiencia = experiencia;
    }

    /**
     * @param item the items to set
     */
    public void setItem(List<Item> item) {
        this.items = item;
    }

    /**
     * @param aliados the aliados to set
     */
    public void setAliados(Aliado[] aliados) {
        this.aliados = aliados;
    }

    /**
     * @param fatiga the fatiga to set
     */
    public void setFatiga(int fatiga) {
        this.fatiga = fatiga;
    }

    /**
     * @param estadoPersistente the estadoPersistente to set
     */
    public void setEstadoPersistente(EstadoPersistente estadoPersistente) {
        this.estadoPersistente = estadoPersistente;
    }

    @Override
    public void hit(int heridas) {
        this.estadoPersistente.addHeridas(heridas);
    }

    @Override
    public String toString() {
        return "["+this.estadoPersistente.getHeridas()+","+this.estadoPersistente.getAgotamiento()+"]"+super.toString();
    }
    
    /**
     * Obtiene la vida actual, con el daño sufirdo
     * @return 
     */
    public int getVidaActual(){
        return this.getVida()-this.getEstadoPersistente().getHeridas();
    }
    
    /**
     * Obtiene el agotamiento actual
     * @return 
     */
    public int getFatigaActual(){
        return this.getFatiga()-this.getEstadoPersistente().getAgotamiento();
    }

    /**
     * Recupera completamente vida y fatiga
     */
    public void recuperarAll() {
        this.setEstadoPersistente(new EstadoPersistente());
    }
    
    
    public int getExperienciaActual(){
        return this.puntosExperiencia;
    }
    
    /**
     * Obtiene la experiencia total. La usada y la pendiente
     * @return 
     */
    public int getExperienciaTotal(){
        int exp = 0;
        for (Experiencia e : experiencia) {
            exp+=e.getExpConsumida();
        }
        return exp+this.puntosExperiencia;
    }

    /**
     * El heroe gana amenaza en función de la amenaza del monstruo
     * @param tipoAmenaza 
     */
    public void ganarExperiencia(TipoAmenaza tipoAmenaza) {
        int puntos =0;
        switch (tipoAmenaza) {
            case VERDE:
                puntos=1;
                break;
            case AMARILLO:
                puntos=2;
                break;
            case AZUL:
                puntos=3;
                break;
            case ROJO:
                puntos=4;
                break;
        }
        this.puntosExperiencia+=puntos; 
    }

    /**
     * Añade una mejora de experiencia al heroe
     * @param exp 
     */
    public void addExperiencia(Experiencia exp) {
        this.puntosExperiencia-=exp.getExpConsumida();
        this.experiencia.add(exp);
    }

    /**
     * Recorre la lista de experiencia aplicando las mejoras al valor
     * @param valor
     * @param atributo
     * @return 
     */
    private int procesarExperienciaHeroe(int valor, Atributo atributo) {
        for (Experiencia exp : experiencia) {
            valor = exp.ampliarAtributos(atributo, valor);
        }
        return valor;
    }
    
    /**
     * Aplica los modificadores producidos por los objetos
     * @param valor
     * @param atributo
     * @return 
     */
    private int procesarItems(int valor, Atributo atributo) {
        for(Item item: this.items){
            if(item instanceof ItemPasiva){
                ItemPasiva arma = (ItemPasiva)item;
                valor = arma.ampliarAtributos(atributo, valor);
                
            }
        }
        return valor;
    }

    /**
     * Gasta oro del Ahorro
     * @param gasto 
     */
    public void gastarOro(int gasto) {
        this.oro-=gasto;
    }

    /**
     * Cura heridas
     * @param heridas
     */
    public void curar(int heridas) {
        this.estadoPersistente.addHeridas((-1)*heridas);
    }

    /**
     * Recupera puntos de fatiga
     * @param fatiga 
     */
    public void recuperar(int fatiga) {
         this.getEstadoPersistente().addAgotamiento((-1)*fatiga);
    }

    public void addItem(Item item) {
        this.items.add(item);
    }
    
    public void removeItem(Item item){
        this.items.remove(item);
    }

    @Override
    public int getFuerzaFisico() {
        int valor = super.getFuerzaFisico(); 
        valor = this.procesarItems(valor, Atributo.FUERZAFISICO);
        return valor;
    }

    @Override
    public int getFuerzaMente() {
        int valor = super.getFuerzaMente(); 
        valor = this.procesarItems(valor, Atributo.FUERZAMENTE);
        return valor;
    }

    @Override
    public int getFuerzaMagia() {
        int valor = super.getFuerzaMagia(); 
        valor = this.procesarItems(valor, Atributo.FUERZAFISICO);
        return valor;
    }
    
    

    
    
    
    
    
    
}
